package org.jmc.refmanager.web.wicket.page.service;

import java.util.List;

import org.apache.wicket.IRequestTarget;
import org.apache.wicket.PageParameters;
import org.apache.wicket.RequestCycle;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.jmc.refmanager.domain.model.OrgUnit;
import org.jmc.refmanager.domain.service.OrgUnitManager;
import org.jmc.refmanager.security.SecurityHelper;
import org.jmc.refmanager.util.Util;
import org.jmc.refmanager.web.wicket.page.navigation.NavigationPage;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class AjaxOrgUnitJsonProviderPage extends WebPage {
	@SpringBean(name="orgUnitManager")
	private OrgUnitManager orgUnitManager;

	public AjaxOrgUnitJsonProviderPage(PageParameters pageParameters) {
		final Integer serviceId;
		final boolean showMenu;
		
		if (pageParameters != null) {
			serviceId = pageParameters.getAsInteger("id", 0);
			showMenu = pageParameters.getAsBoolean("showmenu", true);
		} else {
			serviceId = 0;
			showMenu = true;
		}
		
		final String matricule = SecurityHelper.getAuthentication().getName();
		
		final List<OrgUnit> services;
		final OrgUnit rootService;
		
		// Filter sur le noeud racine disponible dans le scope
		if (serviceId == 0) {
			services = null;
			rootService = orgUnitManager.getRoot(matricule);
		} else {
			// Rechercher les noeuds fils de la selection
			services = orgUnitManager.getChildren(serviceId, matricule);
			rootService = null;
		}
		
		getRequestCycle().setRequestTarget(new IRequestTarget() {
			@Override
			public void detach(RequestCycle requestCycle) {
				// Nothing to do here.
			}

			@Override
			public void respond(RequestCycle requestCycle) {
				JSONArray nodes = new JSONArray();
				
				try {
					if (serviceId == 0) {
						// Affiche les noeuds racines
						JSONObject attributes = new JSONObject();
						attributes.put("id", rootService.getId());
						// Le service racine est une direction de validation
						attributes.put("rel", "disabled");

						JSONObject data = new JSONObject();
						data.put("title", rootService.getLibCourt());

						JSONObject dataAttrs = new JSONObject();
						dataAttrs.put("href", encodeViewUrl(rootService.getId()));
						if (rootService.isSaa()) {
							dataAttrs.put("style", "color: red;");
						}
						data.put("attr", dataAttrs);

						JSONObject node = new JSONObject();
						node.put("data", data);
						node.put("attr", attributes);
						node.put("state", "closed");
	
						nodes.put(node);
					} else {
						// Affiche les fils
						for (OrgUnit service : services) {
							// TODO Cette requete est consommatrice ! Optimisation possible...
							boolean serviceChangeInProgress = (service.getChanges() != null && service.getChanges().size() != 0);
							
							Integer countChildren = orgUnitManager.countChildren(service.getId(), matricule);

							JSONObject attributes = new JSONObject();
							attributes.put("id", service.getId());
							String type = Util.getBlankIfNull(service.getType());
							if (serviceChangeInProgress || "C02".equalsIgnoreCase(type)) {
								// Ne pas afficher le menu si le service est en cours de changement
								// ou si c'est une direction de validation
								attributes.put("rel", "disabled");
							} else {
								if (showMenu) {
									attributes.put("createUrl", encodeCreateUrl(service.getId()));
									attributes.put("editUrl", encodeEditUrl(service.getId()));
									attributes.put("deleteUrl", encodeDeleteUrl(service.getId()));
								}
							}

							JSONObject data = new JSONObject();
							data.put("title", service.getLibCourt());
							if (serviceChangeInProgress) {
								data.put("icon", "styles/plugins/buttons/icons/Hourglass.png");
							}
							
							JSONObject dataAttrs = new JSONObject();
							// T E S T
							if (showMenu) {
								dataAttrs.put("href", encodeViewUrl(service.getId()));
							}
							if (service.isSaa()) {
								dataAttrs.put("style", "color: red;");
							}
							data.put("attr", dataAttrs);
							
							JSONObject node = new JSONObject();
							node.put("data", data);
							node.put("attr", attributes);
							if (countChildren != 0) {
								node.put("state", "closed");
							}
							nodes.put(node);
						}
					}
				} catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				// Add JSON-encoded string to the response.
				requestCycle.getResponse().write(nodes.toString());
			}
		});
	}

	/**
	 * Encodage de l'URL pour la consultation du noeud
	 * 
	 * @param id
	 * @return
	 */
	private String encodeViewUrl(Integer id) {
		PageParameters parameters = new PageParameters();
		parameters.add("id", String.valueOf(id));
		parameters.add("pageOrigin", NavigationPage.class.getName());
		CharSequence url = RequestCycle.get().urlFor(NavigationPage.class, parameters);
//		return url.toString();
		
		StringBuilder b = new StringBuilder("javascript:callWicket(");
		b.append("'").append(String.valueOf(id)).append("');");
		return b.toString();
	}

	/**
	 * Encodage de l'URL pour l'edition du noeud
	 * @param id
	 * @return
	 */
	private String encodeEditUrl(Integer id) {
		PageParameters parameters = new PageParameters();
		parameters.add("id", String.valueOf(id));
		parameters.add("pageOrigin", NavigationPage.class.getName());
		CharSequence url = RequestCycle.get().urlFor(ServiceEditPage.class, parameters);
		return url.toString();
	}

	/**
	 * Encodage de l'URL pour la suppression du noeud
	 * @param id
	 * @return
	 */
	private String encodeDeleteUrl(Integer id) {
		PageParameters parameters = new PageParameters();
		parameters.add("id", String.valueOf(id));
		parameters.add("pageOrigin", NavigationPage.class.getName());
		CharSequence url = RequestCycle.get().urlFor(ServiceDeletePage.class, parameters);
		return url.toString();
	};

	/**
	 * Encodage de l'URL pour la creation du noeud
	 * @param id
	 * @return
	 */
	private String encodeCreateUrl(Integer id) {
		PageParameters parameters = new PageParameters();
		parameters.add("parentId", String.valueOf(id));
		parameters.add("pageOrigin", NavigationPage.class.getName());
		CharSequence url = RequestCycle.get().urlFor(ServiceNewPage.class, parameters);
		return url.toString();
	};

}
